package com.github.icloudpay.pay.core.service.pay;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import com.github.icloudpay.pay.core.biz.PayOrderBiz;
import com.github.icloudpay.pay.core.biz.PaySerialBiz;
import com.github.icloudpay.pay.core.entity.PayOrder;
import com.github.icloudpay.pay.core.entity.PaySerial;
import com.github.wxiaoqi.security.common.admin.pay.request.CallbackRequest;
import com.github.wxiaoqi.security.common.admin.pay.request.CompleteTradeRequest;
import com.github.wxiaoqi.security.common.msg.ResponseCode;
import com.github.wxiaoqi.security.common.util.EntityUtils;


/**
 * 回调服务
 * @author hexufeng
 * 2018-6-7
 */
@EnableAsync
@Service("payCallbackService")
public class PayCallbackService {

	private static final Logger logger = LoggerFactory.getLogger(PayCallbackService.class);

	@Autowired
	private PaySerialBiz paySerialBiz;
	@Autowired
	private PayOrderBiz payOrderBiz;
	@Autowired
	private AmqpTemplate rabbitTemplate;

	/**
	 * 回调服务
	 * @param callbackRequest
	 */
	public void callBack(CallbackRequest callbackRequest) {

		logger.info("第三方支付回调开始：请求号{}，远程流水号{}，交易状态{}",callbackRequest.getRequestNo(),callbackRequest.getRemoteTxJournalNo(),callbackRequest.getStatus());

		PaySerial paySerial = new PaySerial();
		paySerial.setSerialNo(callbackRequest.getRequestNo());
		PaySerial selectPaySerial = paySerialBiz.selectOne(paySerial);

		if(selectPaySerial == null){
			logger.error("第三方支付回调支付订单不存在：请求号{}",callbackRequest.getRequestNo());
			return ;
		}

		if(selectPaySerial.getPayAmt().compareTo(callbackRequest.getOrderAmt())!=0){
			logger.error("第三方支付回调交易金额不正确：回调渠道{}，请求号{}，订单扣款金额{}，第三方支付扣款金额{}",selectPaySerial.getPayChannelNo(),callbackRequest.getRequestNo(), selectPaySerial.getPayAmt() ,callbackRequest.getOrderAmt().toString());
			return ;
		}

		//已成功，不需要处理
		if("00".equals(selectPaySerial.getPayStatus())){
			logger.info("第三方支付回调已处理，不需要再次处理：回调渠道{}，请求号{}，回调状态{}",selectPaySerial.getPayChannelNo(),callbackRequest.getRequestNo(),selectPaySerial.getPayStatus());
			return ;
		}
		//已失败，不需要处理
		if("01".equals(selectPaySerial.getPayStatus())){
			logger.info("第三方支付回调已处理，不需要再次处理：回调渠道{},请求号{},回调状态{}",selectPaySerial.getPayChannelNo(),callbackRequest.getRequestNo(),selectPaySerial.getPayStatus());
			return ;
		}

		PayOrder payOrder = new PayOrder();
		payOrder.setPayOrderNo(selectPaySerial.getPayOrderNo());
		payOrder.setPlatformId(selectPaySerial.getPlatformId());
		PayOrder selectPayOrder = payOrderBiz.selectOne(payOrder);
		if("00".equals(callbackRequest.getStatus())){
			selectPaySerial.setPayStatus("00");//支付成功
			selectPayOrder.setOrderStatus("00");//支付成功
		}else{
			selectPaySerial.setPayStatus("01");//支付失败
			selectPayOrder.setOrderStatus("01");//支付失败
		}
		//更新订单流水(支付订单和收款订单)
		paySerialBiz.updateById(selectPaySerial);
		payOrderBiz.updateById(selectPayOrder);

		//feign调用异步通知商户
		CompleteTradeRequest completeTradeRequest = new CompleteTradeRequest();
		completeTradeRequest.setAmount(String.valueOf(selectPaySerial.getPayAmt()));
		completeTradeRequest.setOrderNo(selectPaySerial.getPayOrderNo());
		completeTradeRequest.setPlatformId(selectPaySerial.getPlatformId());
		completeTradeRequest.setTradeType("1");//支付
		if("00".equals(callbackRequest.getStatus())){
			completeTradeRequest.setTxStatus("00");
		}else{
			completeTradeRequest.setTxStatus("01");
		}
		

		Map<String, Object> callBackResponse = new HashMap<String, Object>();
		int i = 0;
		do {
			i++;
			if (i > 2) // 如果通知失败，尝试重新通知3次
				break;
			try { // 通知商户
				logger.info("通知商户信息---request{}",EntityUtils.beanToMap(completeTradeRequest));
//				callBackResponse = callBackFeign.callBack(completeTradeRequest);
				String context = EntityUtils.beanToMap(completeTradeRequest).toString();
				this.rabbitTemplate.convertAndSend("topic.payment", context);
			} catch (Exception e) {
				logger.error("通知商户信息失败", e);
			}
		} while (callBackResponse != null && ResponseCode.OK.getCode().equals(callBackResponse.get("code")));
		
		logger.info("支付回调结束");
	}

}
